#pragma once
//#include "Comparators.h" ;
#include "Pascal.h"
#include "comparators.h"

#ifndef THandleTableM_H
#define THandleTableM_H
	//template <typename T, typename TComparator>
	//struct TSlot_2;
	template <typename T, typename TComparator>
	class THandleTableM
	{
	public:

		struct TSlot;
		/*{
			Boolean Occupied;
			T Value;
			Boolean operator== (const TSlot a, const TSlot b);
		};*/
		typedef TSlot* PSlot;

		typedef TFPGList<TSlot> TSlots;
		typedef TFPGList<Integer> THandles;
		typedef TComparable<T, TComparator> TComparableItem;
		typedef TFPGMap<TComparableItem, Integer> TObjectToHandleMap;
	public:
		TSlots FSlots;
		THandles FFreeHandles;
		TObjectToHandleMap FValueToHandle;
	public:
		Integer AllocateHandle(T AValue);
		Integer GetKey(Integer AIndex);
		T GetData(Integer AIndex);
		Integer GetCount();
		PSlot GetSlot(Integer AIndex);
	private:
		//property Slots[AIndex: Integer]: PSlot read GetSlot;
	protected:
		Boolean IsValidHandle(Integer AHandle);
	public:
		Integer GetHandle(const T AValue);
		procedure InsertValue(Integer AHandle, const T AValue);
		Boolean GetValue(Integer AHandle, T &Value);
		T GetValue(Integer AHandle);
		Integer CreateHandle(const T AValue);
		procedure FreeHandle(Integer AHandle);
		procedure Clear();
	public:
		//property Items[AHandle: Integer]: T read GetValue write InsertValue; default;
		//property Keys[AIndex: Integer]: Integer read GetKey;
		//property Data[AIndex: Integer]: T read GetData;
		//property Count: Integer read GetCount;
	public:
		THandleTableM();
		~THandleTableM();
	};
#endif

		template <typename T, typename TComparator>
		struct THandleTableM<T,TComparator>::TSlot : public THandleTableM<T,TComparator>
		{
			Boolean Occupied;
			T Value;
			Boolean operator== (const TSlot &b);
			procedure operator= (const TSlot &b);
		};

		//template <typename T, typename TComparator>
		//struct TSlot_2 : public THandleTableM<T,TComparator>::TSlot {};

	template <typename T>
	class THandleTable : public THandleTableM<T, TValueComparator<T>> {};

